package com.landinfo.config;

import com.vividsolutions.jts.awt.PointShapeFactory;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class GeometryUtil {

    public GeometryUtil() {

    }

    private GeometryFactory geometryFactory = new GeometryFactory();


    /**
     * 两个几何对象是否是重叠的
     *
     * @return
     * @throws ParseException
     */
    public boolean equalsGeo() throws ParseException {
        WKTReader reader = new WKTReader(geometryFactory);
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(5 0, 0 0)");
        return geometry1.equals(geometry2);//true
    }

    /**
     * 几何对象没有交点(相邻)
     *
     * @return
     * @throws ParseException
     */
    public boolean disjointGeo() throws ParseException {
        WKTReader reader = new WKTReader(geometryFactory);
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(0 1, 0 2)");
        return geometry1.disjoint(geometry2);
    }

    /**
     * 至少一个公共点(相交)
     *
     * @return
     * @throws ParseException
     */
    public boolean intersectsGeo() throws ParseException {
        WKTReader reader = new WKTReader(geometryFactory);
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(0 0, 0 2)");
        Geometry interPoint = geometry1.intersection(geometry2);//相交点
        System.out.println(interPoint.toText());//输出 POINT (0 0)
        return geometry1.intersects(geometry2);
    }

    /**
     * 判断以x,y为坐标的点point(x,y)是否在geometry表示的Polygon中
     *
     * @param x
     * @param y
     * @param geometry wkt格式
     * @return
     */
    public boolean withinGeo(double x, double y, String geometry) throws ParseException {

        Coordinate coord = new Coordinate(x, y);
        Point point = geometryFactory.createPoint(coord);

        WKTReader reader = new WKTReader(geometryFactory);
        Polygon polygon = (Polygon) reader.read(geometry);
        return point.within(polygon);
    }


    /**
     * create a Point
     *
     * @param x
     * @param y
     * @return
     */
    public Coordinate point(double x, double y) {
        return new Coordinate(x, y);
    }


    /**
     * create a line
     *
     * @return
     */
    public LineString createLine(List<Coordinate> points) {
        Coordinate[] coords = (Coordinate[]) points.toArray(new Coordinate[points.size()]);
        LineString line = geometryFactory.createLineString(coords);
        return line;
    }

    /**
     * 返回a指定距离内的多边形和多多边形
     *
     * @param a
     * @param distance
     * @return
     */
    public Geometry bufferGeo(Geometry a, double distance) {
        return a.buffer(distance);
    }

    /**
     * 返回(A)与(B)中距离最近的两个点的距离
     *
     * @param a
     * @param b
     * @return
     */
    public double distanceGeo(Geometry a, Geometry b) {
        return a.distance(b);
    }

    /**
     * 两个几何对象的交集
     *
     * @param a
     * @param b
     * @return
     */
    public Geometry intersectionGeo(Geometry a, Geometry b) {
        return a.intersection(b);
    }

    /**
     * 几何对象合并
     *
     * @param a
     * @param b
     * @return
     */
    public Geometry unionGeo(Geometry a, Geometry b) {
        return a.union(b);
    }

    /**
     * 在A几何对象中有的，但是B几何对象中没有
     *
     * @param a
     * @param b
     * @return
     */
    public Geometry differenceGeo(Geometry a, Geometry b) {
        return a.difference(b);
    }

    public Point createPoint(Double lon, Double lat, Integer srid) {
        Coordinate coord = new Coordinate(lon, lat);
        Point point = geometryFactory.createPoint(coord);
        if (point != null && srid != null) {
            point.setSRID(srid);
        }
        return point;
    }

    /**
     * create a point by WKT
     *
     * @param wkt
     * @param srid
     * @return
     * @throws ParseException
     */
    public Point createPointByWKT(String wkt, Integer srid) throws ParseException {
        WKTReader reader = new WKTReader(geometryFactory);
        // Point point = (Point) reader.read("POINT (109.013388 32.715519)");
        Point point = (Point) reader.read(wkt);
        if (srid != null && point != null) {
            point.setSRID(srid);
        }
        return point;
    }


}
